梦入琼楼寒有月,行过石树冻无烟

Laravel 路由

Laravel路由与Spring boot的控制器相差无几,相信学过Spring boot的读者会感觉Laravel非常的和蔼可亲,甚至比Spring boot更好理解。通过阅读前面的Laravel的文件结构我们可以得知,在app/reutes/web.php文件中定义路由,在这里面的路由通常都会被分配给web中间件组,在不为人知的情况下,他还提供了会话状态和CSRF保护的作用

路由的定义


在Laravel中,为我们提供了一个简洁优雅的定义路由语法,为:

1
2
3
Route::get('/hey', function () {
return 'hello,world!';
});

视图路由

当然此时你觉得单纯的返回字符串已经完全满足不了需求了,这个时候我们可以在定义一个视图(view)路由,需要注意的视图路由通常存放在resources/view/目录下:

1
2
3
Route::get('/', function () {
return view('welcome');
});

这个时候如果你访问localhost:8000则会跳转至/reousces/view/welcome.blade.php文件所呈现的视图。

重定向路由(redirect)

重定向路由即访问$url后跳转至另外一个url,而不会产生任何的报错即称之为“重定向”,通俗了说就是你在你家开了房门,发现外面并不是自己的家就为重定向:

重定向到另一个视图

1
Route::redirect('/hey', '/');

即访问http://localhost:8000/hey,重定向到'/'所显示的视图```/resources/view/welcome.blade.php```。

重定向到上一个页面

1
2
3
Route::get('/hey', function () {
return redirect()->back();
});

在Laravel之中,我们也可通过Route::get的方式来进行重定向,而最终执行重定向的是return redirect,只不过第一种方法更加的简洁。

路由参数

路由参数通常是指用于传递的一些信息,主要分为两类,分别为必要参数以及一个可选参数,本文我们主要通过获取id以及名称来进行不同的演示:

必要参数

1
2
3
Route::get('id/{id}', function ($id) {
echo "我的ID是:".$id;
});

可通过访问localhost:8000/id/8012来访问自己的id,所返回的结果也一定是我的ID是:8012

可选参数

可选参数与必要参数的区别就是,可选参数允许你提交空值,之后所返回的不是404而是默认定义的字符串或数值。如通过必要参数时,你访问localhost:8000/id/则会返回404,但是如果使用可选参数将会返回默认的值,定义方法如下:

1
2
3
4
5
6
7
Route::get('user/{name?}', function ($name = null) {
return $name;
});

Route::get('user/{name?}', function ($name = 'test') {
return $name;
});

这样你如果访问localhost:8000/user/不会返回404,而是返回test信息。

路由约束

路由约束可分为正则表达式约束、全局约束两种方式,可以理解为使用正则表达式来约束单个路由,使用全局约束来约束全部路由:

正则表达式约束

使用正则表达式约束需要配合where来定义一个正则表达式用于约束该路由:

单个函数约束

1
2
3
Route::get('id/{id}', function ($id) {
echo "我的ID是:".$id;
})->where('id','[0-9]+');

多个函数约束

1
2
3
Route::get('user/{id}/{name}', function ($id, $name) {
echo "当前用户ID:".$id . ",名称是:" . $name;
})->where(['id' => '[0-9]+', 'name' => '[A-Za-z]+']);

此时如果你访问http://localhost:8000/user/1/test将会显示“当前用户ID:1,名称是:test”,但是如果不按照正则表达式约束则会出现404的错误,如http://localhost:8000/user/1s/test

全局约束

在Laravel项目中,全局约束由app/Providers/RouteServiceProvider.php所定义,具体为在19行左右之中:

1
2
3
4
5
6
7
8
9
10
11
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
// 定义id函数仅允许0-9的输入回显
Route::pattern('id','[0-9]+');
parent::boot();
}

routes/web.php文件内容如下:

1
2
3
Route::get('user/{id}', function ($id) {
echo "我的ID是:".$id;
});

之后通过http://localhost:8000/user/11s访问则会出现404错误,如按照全局约束文件内定义访问```http://localhost:8000/user/11```则会回显“我的ID是:11”数据。

路由命名

路由命名可以为指定的路由生成一个url或者重定向,可以通过name来指定路由名称:

1
2
3
4
5
6
7
Route::get('/test', function () {
return view('test');
});

Route::get('user/{id?}', function ($id = 1) {
echo "我的ID是:".$id;
})->name('user.id');

路由名称前缀

后续我们会有一个路由前缀,而为了简便开发,Laravel还提供了一个路由名称前缀,来方便我们与视图的对接:

1
2
3
4
5
6
7
8
9
10
11
Route::group([], function () {
Route::get('/test', function () {
return view('test');
});
Route::name('user.')->group(function () {
Route::get('user/{id?}', function ($id = 1) {
echo "ID is be:" .$id;
})->name('id');
});
……
});

当然我们这还加上了路由分组,来让代码的可读性和延伸扩展性进行了一系列的优化,而这个路由前缀的最后结果为user.id,我们可以继续。

test.blade.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Laravel</title>

<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
<body>
<a href="{{route('user.id', ['id' => 10])}}">go></a>
</body>
</head>
</html>

路由分组

在Laravel框架中,路由分组可以通过使用Route::group将不同的路由分别划分在一起,来让代码更加的简洁优雅:

1
2
3
4
5
6
7
8
9
Route::group([],function () {
Route::get('/test', function () {
return view('test');
});

Route::get('user/{id?}', function ($id = 1) {
echo "我的ID是:".$id;
})->name('user.id');
});

子域名路由

顾名思义即用于处理子域名的路由,如pv.zsun.org.cn就是一个子路由,本文仅仅用于演示语法,该语法并不具有可执行性,想实现的读者可通过配置服务器应用文件即可。

1
2
3
4
5
6
7
Route::domain('{er}.url.org.cn')->group(function () {
Route::get('user/{id}', function ($er, $id) {
// code
echo "当前子域名为:".$er;
echo "用户ID为:".$id;
});
});

域名前缀

1
2
3
4
5
6
Route::prefix('one')->group(function () {
Route::get('two', function () {
// 即 localhost:8000/one/two
echo "one/two";
});
});

域名前缀偶尔会让读者产生一丝的误会,实际上域名前缀指的是一个一个目录下包含着的一些文件,以这个为比喻可能更加方便读者的理解,如上述我们所写的域名前缀则意为:

one/下的/two,即可通过http://localhost:8000/one/two进行访问,当然我们也可以定义一个three:

1
2
3
4
5
6
7
8
9
Route::prefix('one')->group(function () {
Route::get('two', function () {
// 即 localhost:8000/one/two
echo "one/two";
});
Route::get('three', function () {
echo "one/three";
});
});
⬅️ Go back